package handler

import (
	"net/http"
	"strconv"

	"go-file-perception-model/internal/logger"
	"go-file-perception-model/internal/model"
	"go-file-perception-model/internal/service"

	"go.uber.org/zap"

	"github.com/gin-gonic/gin"
)

// DirectoryTreeHandler 目录树处理器
type DirectoryTreeHandler struct {
	directoryTreeService *service.DirectoryTreeService
}

// NewDirectoryTreeHandler 创建目录树处理器实例
func NewDirectoryTreeHandler(directoryTreeService *service.DirectoryTreeService) *DirectoryTreeHandler {
	return &DirectoryTreeHandler{
		directoryTreeService: directoryTreeService,
	}
}

// GetDirectoryTree 处理获取目录树请求
func (h *DirectoryTreeHandler) GetDirectoryTree(c *gin.Context) {
	// 获取查询参数
	directory := c.Query("directory")
	// 允许空目录参数，服务层会使用配置的索引目录作为默认值

	// 解析其他参数
	maxDepthStr := c.DefaultQuery("max_depth", "0")
	maxDepth, err := strconv.Atoi(maxDepthStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid max_depth parameter",
		})
		return
	}

	showHiddenStr := c.DefaultQuery("show_hidden", "false")
	showHidden, err := strconv.ParseBool(showHiddenStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid show_hidden parameter",
		})
		return
	}

	onlyIndexedStr := c.DefaultQuery("only_indexed", "false")
	onlyIndexed, err := strconv.ParseBool(onlyIndexedStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid only_indexed parameter",
		})
		return
	}

	fileFilter := c.Query("file_filter")

	// 构建请求
	req := model.DirectoryTreeRequest{
		Directory:   directory,
		MaxDepth:    maxDepth,
		ShowHidden:  showHidden,
		FileFilter:  fileFilter,
		OnlyIndexed: onlyIndexed,
	}

	// 调用服务层获取目录树
	response, err := h.directoryTreeService.GetDirectoryTree(req)
	if err != nil {
		logger.Error("Failed to get directory tree", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "Failed to get directory tree",
			"error":   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Directory tree retrieved successfully",
		"data":    response,
	})
}

// SearchDirectoryTree 处理目录树搜索请求
func (h *DirectoryTreeHandler) SearchDirectoryTree(c *gin.Context) {
	var req model.DirectoryTreeSearchRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid request format",
			"error":   err.Error(),
		})
		return
	}

	// 允许空目录参数，服务层会使用配置的索引目录作为默认值
	if req.Pattern == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Pattern parameter is required",
		})
		return
	}

	// 设置默认值
	if req.MaxDepth <= 0 {
		req.MaxDepth = 100
	}
	if req.SearchType == "" {
		req.SearchType = "filename"
	}

	// 调用服务层进行搜索
	response, err := h.directoryTreeService.SearchDirectoryTree(req)
	if err != nil {
		logger.Error("Failed to search directory tree", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "Failed to search directory tree",
			"error":   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Directory tree search completed successfully",
		"data":    response,
	})
}

// GetDirectoryTreeByPost 处理POST方式的目录树请求
func (h *DirectoryTreeHandler) GetDirectoryTreeByPost(c *gin.Context) {
	var req model.DirectoryTreeRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid request format",
			"error":   err.Error(),
		})
		return
	}

	// 允许空目录参数，服务层会使用配置的索引目录作为默认值

	// 调用服务层获取目录树
	response, err := h.directoryTreeService.GetDirectoryTree(req)
	if err != nil {
		logger.Error("Failed to get directory tree", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "Failed to get directory tree",
			"error":   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Directory tree retrieved successfully",
		"data":    response,
	})
}
